/***************************************************************************
 *  ActiveUserEvent.cs
 *
 *  Copyright (C) 2005-2006 Novell, Inc.
 *  Written by Aaron Bockover <aaron@abock.org>
 ****************************************************************************/

/*  THIS FILE IS LICENSED UNDER THE MIT LICENSE AS OUTLINED IMMEDIATELY BELOW: 
 *
 *  Permission is hereby granted, free of charge, to any person obtaining a
 *  copy of this software and associated documentation files (the "Software"),  
 *  to deal in the Software without restriction, including without limitation  
 *  the rights to use, copy, modify, merge, publish, distribute, sublicense,  
 *  and/or sell copies of the Software, and to permit persons to whom the  
 *  Software is furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included in 
 *  all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
 *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 *  DEALINGS IN THE SOFTWARE.
 */
 
using System;
using System.Drawing;
using System.Windows.Forms;
 
namespace Banshee.Winforms.Controls
{
    public class ActiveUserEvent : UserControl
    {

        private string tips;
        
        private double progress = 0.0;
        private string name;
        private string message;
        private string header;
        private string cancel_message;

        private bool message_update_needed = false;
        private bool header_update_needed = false;
        private bool progress_update_needed = false;
        private delegate void timeout_delegate();
        
        private uint timeout_id = 0;
        private uint slow_timeout_id = 0;
        private bool disposed = false;
        
        public event EventHandler CancelRequested;

       private Icon icon;

        private bool cancel_requested;
        private Label header_label;
        private Label message_label;
        private PictureBox p_box;
        private Panel panel1;
        private ProgressBar progress_bar;
        private Button cancel_button;
        private bool can_cancel;

        public ActiveUserEvent(string name) : this(name, false) 
        {
        }
        /*
        void CreateControls()
        {
            table = new Control();
            header_label = new Label();
            message_label = new Label();
            progress_bar = new ProgressBar();
            
            cancel_button = new Button();
            cancel_button.Click+=new EventHandler(cancel_button_Click);
            table.Controls.Add(header_label);
            header_label.Dock = DockStyle.Top;
            table.Controls.Add(message_label);
            message_label.AutoSize = false;
            message_label.Dock = DockStyle.Fill;
            table.Controls.Add(progress_bar);
            progress_bar.Height = 10;
            progress_bar.Dock = DockStyle.Bottom;
            cancel_button.Image = Image.FromFile(Application.StartupPath + @"\icons\process-stop.png");
            cancel_button.TextImageRelation = TextImageRelation.ImageBeforeText;
            cancel_button.Text = "Cancel";
            
            cancel_button.Dock = DockStyle.Right;
            message_label.BringToFront();
            PictureBox p_box = new PictureBox();
            p_box.Width = 32;
            p_box.Height = 32;
            if(icon != null)
            p_box.Image = icon.ToBitmap();
            else
            p_box.Image = Image.FromFile(Application.StartupPath + @"\icons\icon-title.png");

            Panel button_panel = new Panel();
            button_panel.Height = 34;
            button_panel.Dock = DockStyle.Bottom;
            table.Controls.Add(button_panel);
            button_panel.SendToBack();
            p_box.Dock = DockStyle.Left;
            button_panel.Controls.Add(p_box);
            button_panel.Controls.Add(cancel_button);
            ActiveUserEventsManager.Register(this);
        }*/
        public ActiveUserEvent(string name, bool delayShow)
        {

            InitializeComponent();
            //CreateControls();
            Name = name;
            Progress = 0.0;
            if(delayShow) {
                slow_timeout_id = 1000;
                 OnCheckForDisplay();
            } else {
                ActiveUserEventsManager.Register(this);
            }
            OnUpdateStatus();

        }
        void cancel_button_Click(object sender, EventArgs e)
        {
            string msg = String.Format(
                            "The '{0}' operation is still performing work. Would you like to stop it?", name);
           DialogResult dr =  MessageBox.Show(msg,string.Format("Stop {0}", name), MessageBoxButtons.YesNo,MessageBoxIcon.Question);
           if (dr == DialogResult.Yes)
               Cancel();
        }
        public void Cancel()
        {
            EventHandler handler = CancelRequested; 
            if(handler != null) {
                handler(this, new EventArgs());
            }    
            
            cancel_requested = true;       
        }
        private bool OnCheckForDisplay()
        {
            if(disposed) {
                return false;
            }
            
            // If the event has not made enough progress, show this event
            if(Progress < 0.33) {
                ActiveUserEventsManager.Register(this);
            }
            
            return false;
        }
        public void Destroy()
        {
            
        }
        public bool OnUpdateStatus()
        {
            if (Parent.InvokeRequired)
                Parent.Invoke((MethodInvoker)delegate() { OnUpdateStatus(); });
            else
            {
                if (disposed)
                {
                    Banshee.Base.LogCore.Instance.PushInformation("Active Event", "Event disposed");
                    return false;
                }
                else if (!header_update_needed && !message_update_needed && !progress_update_needed)
                {
                    return true;
                }

                if (header_update_needed)
                {
                    header_label.Visible = header != null;

                    if (header != null)
                    {
                        header_label.Text = header;//.Markup = String.Format("<small><b>{0}</b></small>", GLib.Markup.EscapeText(header));
                    }

                    header_update_needed = false;
                }

                if (message_update_needed)
                {
                    if (message == null && name != null)
                    {
                        message = name;
                    }
                    else if (message == null && name == null)
                    {
                        message = "Performing Task";
                    }

                    message_label.Text = message;//.Markup = String.Format("<small>{0}</small>", GLib.Markup.EscapeText(message));

                    string tip = name + ": " + message;
                    //tips.SetTip(message_label, tip, tip);
                    //tips.SetTip(icon, tip, tip);

                    message_update_needed = false;
                }

                if (progress_update_needed)
                {
                    if (progress > 0.0)
                    {
                        int val = (int)(progress * 100.0);

                        progress_bar.Value = val;
                        //progress_bar.Text = String.Format("{0}%", (int)(progress * 100.0));
                        progress_update_needed = false;
                    }
                    else
                    {
                       // progress_bar.Text = " ";
                        //progress_bar.Pulse();
                        // NOTE: progress_update_needed is intentionally not reset here
                    }
                }
            }
            return true;
        }

        public string Name {
            get { return name; }
            set { 
                name = value; 
                message_update_needed = true; 
            }
        }
        
        public string Message {
            get { return message; }
            set {
                message = value;
                message_update_needed = true;
            }
        }
        
        public string Header {
            get { return header; }
            set {
                header = value;
                header_update_needed = true;
            }
        }
        
        public string CancelMessage {
            get { return cancel_message; }
            set { cancel_message = value; }
        }
        
        public double Progress {
            get { return progress; }
            set {
                progress = value;
                progress_update_needed = true;
            }
        }
        
        public bool CanCancel {
            get { return can_cancel; }
            set {
                can_cancel = value;
                cancel_button.Enabled = value;
            }
        }
        
        public bool IsCancelRequested {
            get { return cancel_requested; }
        }

        private System.Windows.Forms.Control host;

        public System.Windows.Forms.Control Host
        {
            get { return host; }
            set { host = value; }
        }
        public Icon Icon
        {
            get { return icon; }
            set { icon = value; }
           
        }
        public Control Widget
        {
            get { return this; }
        }

        private void InitializeComponent()
        {
            this.header_label = new System.Windows.Forms.Label();
            this.message_label = new System.Windows.Forms.Label();
            this.panel1 = new System.Windows.Forms.Panel();
            this.progress_bar = new System.Windows.Forms.ProgressBar();
            this.cancel_button = new System.Windows.Forms.Button();
            this.p_box = new System.Windows.Forms.PictureBox();
            this.panel1.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.p_box)).BeginInit();
            this.SuspendLayout();
            // 
            // header_label
            // 
            this.header_label.Dock = System.Windows.Forms.DockStyle.Top;
            this.header_label.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.header_label.Location = new System.Drawing.Point(0, 0);
            this.header_label.Name = "header_label";
            this.header_label.Size = new System.Drawing.Size(164, 20);
            this.header_label.TabIndex = 0;
            this.header_label.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
            // 
            // message_label
            // 
            this.message_label.Dock = System.Windows.Forms.DockStyle.Fill;
            this.message_label.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.message_label.Location = new System.Drawing.Point(0, 20);
            this.message_label.Name = "message_label";
            this.message_label.Size = new System.Drawing.Size(164, 17);
            this.message_label.TabIndex = 1;
            this.message_label.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
            // 
            // panel1
            // 
            this.panel1.Controls.Add(this.progress_bar);
            this.panel1.Controls.Add(this.cancel_button);
            this.panel1.Controls.Add(this.p_box);
            this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom;
            this.panel1.Location = new System.Drawing.Point(0, 37);
            this.panel1.Name = "panel1";
            this.panel1.Size = new System.Drawing.Size(164, 18);
            this.panel1.TabIndex = 3;
            // 
            // progress_bar
            // 
            this.progress_bar.Dock = System.Windows.Forms.DockStyle.Fill;
            this.progress_bar.Location = new System.Drawing.Point(16, 0);
            this.progress_bar.Name = "progress_bar";
            this.progress_bar.Size = new System.Drawing.Size(132, 18);
            this.progress_bar.TabIndex = 4;
            // 
            // cancel_button
            // 
            this.cancel_button.Dock = System.Windows.Forms.DockStyle.Right;
            this.cancel_button.Image = global::Banshee.Base.Properties.Resources.process_stop;
            this.cancel_button.Location = new System.Drawing.Point(148, 0);
            this.cancel_button.Name = "cancel_button";
            this.cancel_button.Size = new System.Drawing.Size(16, 18);
            this.cancel_button.TabIndex = 3;
            this.cancel_button.UseVisualStyleBackColor = true;
            this.cancel_button.Click += new System.EventHandler(this.cancel_button_Click);
            // 
            // p_box
            // 
            this.p_box.Dock = System.Windows.Forms.DockStyle.Left;
            this.p_box.Location = new System.Drawing.Point(0, 0);
            this.p_box.Name = "p_box";
            this.p_box.Size = new System.Drawing.Size(16, 18);
            this.p_box.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
            this.p_box.TabIndex = 2;
            this.p_box.TabStop = false;
            // 
            // ActiveUserEvent
            // 
            this.BackColor = System.Drawing.Color.Transparent;
            this.Controls.Add(this.message_label);
            this.Controls.Add(this.panel1);
            this.Controls.Add(this.header_label);
            this.Name = "ActiveUserEvent";
            this.Size = new System.Drawing.Size(164, 55);
            this.Load += new System.EventHandler(this.ActiveUserEvent_Load);
            this.panel1.ResumeLayout(false);
            ((System.ComponentModel.ISupportInitialize)(this.p_box)).EndInit();
            this.ResumeLayout(false);

        }

        private void ActiveUserEvent_Load(object sender, EventArgs e)
        {
            ActiveUserEventsManager.Register(this);
            header_update_needed = true;
            message_update_needed = true;
            progress_update_needed = true;
            OnUpdateStatus();
            timeout_id = 100;
            if (this.icon != null)
                p_box.Image = icon.ToBitmap();
            else
            p_box.Image = Image.FromFile(Application.StartupPath + @"\icons\icon-title.png");
        }
    }
}
